//
// Created by LiuYou on 2021/5/19.
//

#include <cstdio>
#include <cstdlib>
#include <csetjmp>

static std::jmp_buf save{};

static void d() {
    std::printf("%s():Begin\n", __FUNCTION__);

    std::printf("%s():Jump now!\n", __FUNCTION__);
    longjmp(save, 6);

    std::printf("%s():End\n", __FUNCTION__);
}

static void c() {
    std::printf("%s():Begin\n", __FUNCTION__);
    std::printf("%s():Invoke c()\n", __FUNCTION__);
    d();
    std::printf("%s():c() returned\n", __FUNCTION__);
    std::printf("%s():End\n", __FUNCTION__);
}

static void b() {
    std::printf("%s():Begin\n", __FUNCTION__);
    std::printf("%s():Invoke c()\n", __FUNCTION__);
    c();
    std::printf("%s():c() returned\n", __FUNCTION__);
    std::printf("%s():End\n", __FUNCTION__);
}

static void a() {
    std::printf("%s():Begin\n", __FUNCTION__);
    int ret = setjmp(save);
    if (ret == 0) {
        std::printf("%s():Invoke b()\n", __FUNCTION__);
        b();
        std::printf("%s():b() returned\n", __FUNCTION__);
    } else {
        std::printf("%s():Jumped back here with code %d\n", __FUNCTION__, ret);
    }
    std::printf("%s():End\n", __FUNCTION__);
}

int main(int argc, char** argv) {
    std::printf("%s():Begin\n", __FUNCTION__);
    std::printf("%s():Invoke a()\n", __FUNCTION__);
    a();
    std::printf("%s():a() returned\n", __FUNCTION__);
    std::printf("%s():End\n", __FUNCTION__);


    std::exit(0);
}